package com.socio.behaviors;

import java.util.Arrays;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.socio.model.User;
import com.socio.utils.FieldAccessor;
import com.socio.utils.FieldAccessor.FieldAccessorField;

/**
 *
 * @author potlow
 */
public class UserUDIDBehavior extends UserBehavior {

	/**
	 * Makes sure search filter is valid type
	 * 
	 * @param value filter value
	 * @return value of correct type
	 */
	private String checkFilter(Object value) {
		String androidUDID;
        if (value instanceof String) {
            androidUDID = (String) value;
            if(androidUDID.isEmpty())
            	throw new IllegalArgumentException("Search value must not be empty");
        } else {
            throw new IllegalArgumentException("Search value must be a Key");
        }
        
        return androidUDID;
	}
	
    @SuppressWarnings("unchecked")
	@Override
    public List<Object> read(Object filter, List<FieldAccessorField> touchFields) {
    	PersistenceManager pm = pmf.getPersistenceManager();
    	
    	String androidUDID = checkFilter(filter);

        // check cache first if not there get from db and put into cache
        User user = null;
        if(cache.containsKey(androidUDID)) {
        	user = (User)cache.get(androidUDID);
        } else {
        	Query query = null;
        	try {
        		query = pm.newQuery(User.class);
                query.setFilter("androidUDID == androidUDIDParam");
                query.declareParameters("String androidUDIDParam");
        		List<Object> userList = (List<Object>)query.execute(androidUDID);
        		if(!userList.isEmpty())
        			user = (User)userList.get(0);
        		
        		// put user in cache by all its available unique IDs
        		if(user != null) {
        			FieldAccessor.accessFields(user, null, null, touchFields);
        			String facebookID = user.getFacebookID();
        			cache.put(androidUDID, user);
        			cache.put(user.getKey(), user);
        			if(!facebookID.isEmpty())
        				cache.put(facebookID, user);
        		}
        	} finally {
	            query.closeAll();
	            pm.close();
	        }
        }
        
        return Arrays.asList((Object)user);
    }

	@SuppressWarnings("unchecked")
	@Override
	public Object update(Object filter, List<FieldAccessorField> updateFields, List<Object> updatedValues,
			List<FieldAccessorField> touchFields) {
		PersistenceManager pm = pmf.getPersistenceManager();
    	
        String androidUDID = checkFilter(filter);

        // check cache first if not there get from db and put into cache
        User user = null;
    	Query query = null;
    	try {
    		query = pm.newQuery(User.class);
    		query.setFilter("androidUDID == androidUDIDParam");
            query.declareParameters("String androidUDIDParam");
    		List<Object> userList = (List<Object>)query.execute(androidUDID);
    		if(!userList.isEmpty())
    			user = (User)userList.get(0);
    		
    		// remove user in cache by all its available unique IDs
    		if(user != null) {
    			FieldAccessor.accessFields(user, updateFields, updatedValues, touchFields);
    			String facebookID = user.getFacebookID();
    			cache.remove(androidUDID);
    			cache.remove(user.getKey());
    			if(!facebookID.isEmpty())
    				cache.put(facebookID, user);
    		}
    	} finally {
            query.closeAll();
            pm.close();
        }
    	
    	return user;
	}
}
